Ext.define('Seq.button.Segmented', {
    extend: 'Ext.button.Segmented',
    xtype: 'xsegmentedbutton',

    cls: 'sencha-segmented-toolbar',

    config: {
        segments: undefined,
        displayed: 3
    },

    menuCheckHandler(menu, checked) {
        if (checked) {
            var vm = menu.up('[viewModel]').getViewModel(), btn = menu.up().up().up();
            var name = btn.getBind().value.stub.name, oldValue = vm.get(name);
            vm.set(name, menu.value);
        }
    },

    uncheckMenu(newValue) {
        var menu = this.down('#more');
        menu && menu.menu.items.items.forEach(function (item) {
            if (item.value !== newValue) {
                item.setChecked(false);
            }
        });
    },

    listeners: {
        change(view, newValue, oldValue, eOpts) {
            var me = this;
            if (Ext.isEmpty(newValue) || Ext.isNumber(newValue)) {
                return;
            }
            var items = me.items.items, i, len = items.length;
            for (i = 0; i < len; i++) {
                items[i].removeCls('active');
            }
            var item = me.down('button[value=' + newValue + ']') || me.down('#more');
            item && item.addCls('active');
            me.uncheckMenu(newValue);
        }
    },

    privates: {
        _lookupButtonByValue(value) {
            var me = this, btn = me.callParent(arguments);
            if (!btn) {
                btn = me.down('#more');
            }
            return btn;
        }
    },

    segments2items(segments) {
        var items = [];
        for (var i = 0; i < this.displayed; i++) {
            var item = segments.shift();
            item && items.push(item);
        }
        if (0 < segments.length) {
            var item = {
                style: {
                    'padding-left': '0px !important;',
                    'padding-right': '0px !important;'
                },
                text: '更多',
                itemId: 'more',
                menu: []
            };
            while (0 < segments.length) {
                var menu = segments.shift();
                Ext.apply(menu, {
                    checked: false,
                    group: 'segment',
                    checkHandler: this.menuCheckHandler
                });
                item.menu.push(menu);
            }
            items.push(item);
        }
        return items;
    },

    setValue(value) {
        let me = this;
        if (Ext.isNumber(value) || Ext.isEmpty(value)) {
            return;
        }
        if (Ext.isEmpty(me.items.items)) {
            me.add(me.segments2items(me.getSegments()));
        }
        me.callParent(arguments);
    },

    updateValue: function (value, oldValue) {
        let me = this;
        if (Ext.isEmpty(me.items.items) || Ext.isEmpty(value) || Ext.isNumber(value)) {
            return;
        }
        me.callParent(arguments);
    },

    applyValue: function (value, oldValue) {
        let me = this;
        if (Ext.isEmpty(me.items.items) || Ext.isEmpty(value) || Ext.isNumber(value)) {
            return;
        }

        var allowMultiple = me.getAllowMultiple(),
            buttonValue, button, values, oldValues, items, i, ln, hasPressed;

        values = (value instanceof Array) ? value : (value == null) ? [] : [value];
        oldValues = (oldValue instanceof Array) ? oldValue :
            (oldValue == null) ? [] : [oldValue];

        // Set a flag to tell our toggle listener not to respond to the buttons' toggle
        // events while we are applying the value.
        me._isApplyingValue = true;

        if (!me.rendered) {
            // first time - add values of buttons with an initial config of pressed:true
            items = me.items.items;
            for (i = items.length - 1; i >= 0; i--) {
                button = items[i];

                // If we've got back to zero with no pressed buttons and have forceSelection,
                // then make button zero pressed.
                if (me.forceSelection && !i && !hasPressed) {
                    button.pressed = true;
                }
                if (button.pressed) {
                    hasPressed = true;
                    buttonValue = button.value;
                    if (buttonValue == null) {
                        buttonValue = me.items.indexOf(button);
                    }

                    // We're looping backwards, unshift the values into the front of the array
                    if (!Ext.Array.contains(values, buttonValue)) {
                        values.unshift(buttonValue);
                    }
                }
            }
        }

        ln = values.length;

        //<debug>
        if (ln > 1 && !allowMultiple) {
            Ext.raise('Cannot set multiple values when allowMultiple is false');
        }
        //</debug>

        // press all buttons corresponding to the values
        for (i = 0; i < ln; i++) {
            value = values[i];
            button = me._lookupButtonByValue(value);

            if (button) {
                buttonValue = button.value;

                if ((buttonValue != null) && buttonValue !== value) {
                    // button has a value, but it was matched by index.
                    // transform the index into the button value
                    values[i] = buttonValue;
                }

                if (!button.pressed) {
                    button.setPressed(true);
                }
            }
            //<debug>
            else {
                // no matched button. fail.
                Ext.raise("Invalid value '" + value + "' for segmented button: '" + me.id + "'");
            }
            //</debug>
        }

        value = allowMultiple ? values : ln ? values[0] : null;

        // unpress buttons for the old values, if they do not exist in the new values array
        for (i = 0, ln = oldValues.length; i < ln; i++) {
            oldValue = oldValues[i];
            if (!Ext.Array.contains(values, oldValue)) {
                me._lookupButtonByValue(oldValue).setPressed(false);
            }
        }

        me._isApplyingValue = false;

        return value;
    }

});